﻿using System;
using System.Diagnostics;
using Comdiv.QWeb.ViewEngine;

namespace Comdiv.QWeb.Renders {
	public class QViewRender : IRender, IRegistryBound {
		private IQViewFactory factory;
		private QWebServiceRegistry registry;

		#region IRegistryBound Members

		public void SetRegistry(QWebServiceRegistry registry) {
			this.registry = registry;
			factory = this.registry.QViewFactory;
		}

		public QWebServiceRegistry Registry {
			get { return registry; }
		}

		#endregion

		#region IRender Members

		public void Render(QWebContext context) {
			context.ContentType = "text/html";
			var viewname = getViewName(context);
			if (string.IsNullOrWhiteSpace(viewname)) {
				viewname = ("/" + context.ActionName.Replace(".", "/")).Replace("//", "/");
			}
			context.MasterViewName = getLayout(context);
			var ctx = new QViewContext();
			ctx.Name = viewname;
			ctx.Master = context.MasterViewName;
			ctx.ViewData = getViewData(context);
			ctx.Context = context;
			ctx.OutputErrors = context.get("outputerrors", true);
			ctx.Factory = factory;
			var view = factory.GetView(ctx);
			var sw = Stopwatch.StartNew();
			view.Process();
			sw.Stop();
			Registry.Statistics.QViewEngineStatistics.Renders++;
			Registry.Statistics.QViewEngineStatistics.RenderTime += sw.Elapsed;
			if (Registry.Statistics.QViewEngineStatistics.ViewStats.ContainsKey(ctx.Name)) {
				Registry.Statistics.QViewEngineStatistics.ViewStats[ctx.Name].Renders++;
				Registry.Statistics.QViewEngineStatistics.ViewStats[ctx.Name].RenderTime += sw.Elapsed;
			}
		}

		public void RenderError(Exception error, QWebContext context) {
			context.ContentType = "text/html";
			context.Output.Write("<div class='error'><h2>error on " + context.ActionName + "</h2><textarea cols='60' rows='10'>" +
			                     error.ToString().Replace("<", "&lt;") + "</textarea></div>");
		}

		public virtual bool NeedResult {
			get { return true; }
		}

		#endregion

		protected virtual object getViewData(QWebContext context) {
			return context.ActionResult;
		}

		protected virtual string getLayout(QWebContext context) {
			var layout = context.MasterViewName;
			if (string.IsNullOrWhiteSpace(context.MasterViewName) && !string.IsNullOrWhiteSpace(context.get("layout"))) {
				layout = context.get("layout");
			}
			return layout;
		}

		protected virtual string getViewName(QWebContext context) {
			return context.ViewName;
		}
	}
}